﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text;

namespace Comteck.Dto.Common {
  /// <summary>
  /// 
  /// </summary>
  [AttributeUsage(AttributeTargets.Property)]
  public class MinValueAttribute : ValidationAttribute {
    public double MinValue { get; }

    public MinValueAttribute(double minValue) {
      this.MinValue = minValue;
    }
  }

  public static class MinValueExtension {
    public static bool GreaterThan<T>(this T t, string propertyName, out decimal minValue) where T : new() {
      minValue = decimal.Zero;
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MinValueAttribute))) {
        MinValueAttribute attribute = (MinValueAttribute) pi.GetCustomAttribute(typeof(MinValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          minValue = attribute.MinValue.To<decimal>();

          return value > minValue;
        }
      }

      return true;
    }

    public static bool GreaterEqualThan<T>(this T t, string propertyName, out decimal minValue) where T : new() {
      minValue = decimal.Zero;
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MinValueAttribute))) {
        MinValueAttribute attribute = (MinValueAttribute) pi.GetCustomAttribute(typeof(MinValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          minValue = attribute.MinValue.To<decimal>();

          return value >= minValue;
        }
      }

      return true;
    }

    public static void GreaterThanValidate<T>(this T t, string propertyName) where T : new() {
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MinValueAttribute))) {
        MinValueAttribute attribute = (MinValueAttribute) pi.GetCustomAttribute(typeof(MinValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          if (value <= attribute.MinValue.To<decimal>()) {
            throw new ComteckException(string.Format(attribute.ErrorMessage, propertyName, attribute.MinValue));
          }
        }
      }
    }

    public static void GreaterEqualThanValidate<T>(this T t, string propertyName) where T : new() {
      Type type = t.GetType();
      PropertyInfo pi = type.GetProperty(propertyName);
      if (pi != null && pi.IsDefined(typeof(MinValueAttribute))) {
        MinValueAttribute attribute = (MinValueAttribute) pi.GetCustomAttribute(typeof(MinValueAttribute));
        if (attribute != null) {
          decimal value = pi.GetValue(t, null).To<decimal>();
          if (value < attribute.MinValue.To<decimal>()) {
            throw new ComteckException(string.Format(attribute.ErrorMessage, propertyName, attribute.MinValue));
          }
        }
      }
    }
  }
}
